//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;
using OpenLS.Spreadsheet.Internals;

namespace OpenLS.Spreadsheet
{
    public class RichTextRun : IOfficeXmlSerializable
    {
        public RichTextRun()
        {

        }
        public RichTextRun(string text)
        {
            Text = text;
        }
        public void CopyFrom(RichTextRun other)
        {
            _paragraph = other._paragraph;
            fontFamily = other.fontFamily;
            rPr = other.rPr.Clone();
            t = other.Text;
        }
        private RichTextParagraph _paragraph;

        public RichTextParagraph Paragraph
        {
            get { return _paragraph; }
            set {if (_paragraph == value)
                return;
                _paragraph = value;
                if (value == null)
                    return;

        }
        }
	
        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("r"))
            {
                Properties = c.ReadOptionalElement<RichTextRunProperties>("rPr");
                using (ReadContext trc = c.Read("t"))
                {
                    Text = trc.ReadString();
                }
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("r"))
            {
                c.WriteOptionalElement(rPr);
                using (WriteContext trc = c.Write("t"))
                {
                    trc.WritePreservedString(Text);
                }
            }
        }

        #endregion

        private RichTextRunProperties rPr;

        internal RichTextRunProperties Properties
        {
            get
            {
                if (rPr == null)
                    rPr = new RichTextRunProperties();
                return rPr;
            }
            set { rPr = value; }
        }
        public bool IsItalic
        {
            get
            {
                return Properties.Italic;
            }
            set
            {
                Properties.Italic = value;
            }
        }
        public FontFamily FontFamily
        {
            get
            {
                if (fontFamily == null)
                    return fontFamily;
                
                string n = Properties.Name;
                if (n == null)
                    return null;
                return new FontFamily(n);

            }
            set
            {
                fontFamily = value;
                if (fontFamily == null)
                {
                    Properties.FontScheme = FontSchemeType.None;
                }
                if (Paragraph != null && Paragraph.Cell != null)
                    OnAttach(Paragraph.Cell);
                else
                    Properties.Name = fontFamily.Source;

            }
        }
        FontFamily fontFamily;
        public UnderlineType Underline
        {
            get
            {
                return Properties.Underline;
            }
            set
            {
                Properties.Underline = value;

            }
        }
        public double FontSize
        {
            get
            {
                return Properties.Size;
            }
            set
            {
                Properties.Size = value;
            }
        }
        public SpreadsheetColor Foreground
        {
            get
            {
                return Properties.Foreground;
            }
            set
            {
                Properties.Foreground = value;
            }
        }
        public bool IsBold
        {
            get
            {
                return Properties.Bold;
            }
            set
            {
                Properties.Bold = value;
            }
        }
        internal int Family
        {
            get
            {
                return Properties.Family;
            }
            set
            {
                Properties.Family = value;
            }
        }
        internal FontSchemeType FontSchemeType
        {
            get
            {
                return Properties.FontScheme;
            }
            set
            {
                Properties.FontScheme = value;
            }
        }
        public VerticalRunAlignment VerticalAlignment
        {
            get
            {
                return Properties.VerticalAlignment;
            }
            set
            {
                Properties.VerticalAlignment = value;
            }
        }
        public bool Shadow
        {
            get
            {
                return Properties.Shadow;
            }
            set
            {
                Properties.Shadow = value;
            }
        }
        public bool Condense
        {
            get
            {
                return Properties.Condense;
            }
            set
            {
                Properties.Condense = value;
            }
        }
        public bool Strike
        {
            get
            {
                return Properties.Strike;
            }
            set
            {
                Properties.Strike = value;
            }
        }
        internal int? CharSet
        {
            get
            {
                return Properties.CharSet;
            }
            set
            {
                Properties.CharSet = value;
            }
        }



        private string t;
        private Cell _cell;

        public string Text
        {
            get { return t; }
            set { if (t == value)
                return;
                PerformUndoableAction(() => t = value, t, (tt => Text = t));
                t = value;
            }
        }

        private delegate void Action();
        void PerformUndoableAction<TValue>(Action action, TValue oldValue, Action<TValue> undoAction)
        {
            if (_cell == null)
            {
                action();
                return;
            }
            using (_cell.Worksheet.Workbook.CreateUndoScope(StringTable.Comment))
            {
                _cell.Worksheet.Workbook.AddUndoAction(oldValue, undoAction);
            }
            action();

        }




        internal void OnAttach(Cell value)
        {
            this._cell = value;
            if (fontFamily == null)
                return;
            FontScheme fontScheme = value.Worksheet.Workbook.Theme.FontScheme;
            if (fontFamily == fontScheme.MajorFont.Latin) //\\
            {
                Properties.FontScheme = FontSchemeType.Major;
            }
            else if (fontFamily == fontScheme.MinorFont.Latin) //\\
            {
                Properties.FontScheme = FontSchemeType.Minor;
            }
            else
            {
                Properties.FontScheme = FontSchemeType.None;
            }
        }

        public void SetValue(DependencyProperty property, object value)
        {
            if (property == TextElement.FontWeightProperty)
            {
                FontWeight w = (FontWeight)value;
                if (w == FontWeights.Bold)
                    IsBold = true;
                if (w == FontWeights.Normal)
                    IsBold = false;
                return;
            }
            throw new NotImplementedException();;
        }

        public object GetValue(DependencyProperty property)
        {
            if (property == TextElement.FontWeightProperty)
            {
                if (IsBold)
                    return FontWeights.Bold;
                return FontWeights.Normal;
            }
            throw new NotImplementedException();;
        }

        public bool SameProperties(RichTextRun r2)
        {
            if (rPr == null)
                return r2.rPr == null;
            return rPr.Equals(r2.rPr);
        }
    }
}